package cn.com.infcn.spider;

import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.mongodb.DBObject;

import cn.com.infcn.spider.domain.DataJob;
import cn.com.infcn.spider.domain.DirectoryJob;
import cn.com.infcn.spider.domain.FtpJob;
import cn.com.infcn.spider.domain.HttpJob;
import cn.com.infcn.spider.domain.Job;
import cn.com.infcn.spider.scheduler.Scheduler;
import cn.com.infcn.spider.util.JsonResult;
import cn.com.infcn.spider.util.MongoDao;
import cn.com.infcn.spider.util.StaticValue;

/**
 * 用来管理所有的job类
 * 
 * @author Ansj
 *
 */
public class SchedulerManager {

	private static final Logger LOG = Logger.getLogger(SchedulerManager.class);

	public static final ConcurrentHashMap<String, Scheduler> SCHEDULER_MAP = new ConcurrentHashMap<>();

	public synchronized static JsonResult start(String jobName) {

		if (SCHEDULER_MAP.containsKey(jobName)) {
			return StaticValue.errMessageJson(jobName + " alreday started!");
		}

		Job job = findJobByName(jobName);

		if (job.getStatus() != 1) {
			return StaticValue.errMessageJson(jobName + " status is " + job.getStatusStr());
		}

		Scheduler scheduler = job.instanceScheduler();
		scheduler.start(); // 启动进程
		SCHEDULER_MAP.put(jobName, scheduler);

		return StaticValue.okMessageJson(jobName + " started!");
	}

	public synchronized static void shutDwon(String jobName) throws InterruptedException {
		Scheduler scheduler = SCHEDULER_MAP.get(jobName);

		if (scheduler == null) {
			return;
		}

		try {
			scheduler.shutdown();
		} catch (Exception e) {
			e.printStackTrace();
			LOG.error(e);
		}

		for (int i = 0; i < 10 && scheduler.isAlive(); i++) {
			LOG.info("to stop " + jobName);
			Thread.sleep(1000L);
		}

		if (scheduler.isAlive()) {
			scheduler.interrupt();
			scheduler.stop();
		}

		SCHEDULER_MAP.remove(jobName);
	}

	public synchronized static void drop(String jobName) throws InterruptedException {
		shutDwon(jobName);

		findJobByName(jobName).instanceScheduler().drop();
	}

	public synchronized static void flush(String jobName) throws InterruptedException {
		shutDwon(jobName);
		start(jobName);
	}

	private static Job findJobByName(String jobName) {

		MongoDao mongoDao = StaticValue.getBean(MongoDao.class, "mongoDao");

		DBObject findById = mongoDao.findById("job", jobName);

		JSONObject json = (JSONObject) JSONObject.toJSON(findById);

		switch (json.getString("jobType")) {
		case "http":
			return JSONObject.toJavaObject(json, HttpJob.class);
		case "data":
			return JSONObject.toJavaObject(json, DataJob.class);
		case "directory":
			return JSONObject.toJavaObject(json, DirectoryJob.class);
		case "ftp":
			return JSONObject.toJavaObject(json, FtpJob.class);
		default:
			throw new RuntimeException("not find job by name " + jobName);
		}
	}

	public static Job getJob(String jobName) {
		if (SCHEDULER_MAP.containsKey(jobName)) {
			return SCHEDULER_MAP.get(jobName).getJob();
		} else {
			return null;
		}
	}

	/**
	 * 从队列中移出一个key.不可外部调用
	 * 
	 * @param job
	 */
	public static void removeKey(Job job) {
		SCHEDULER_MAP.remove(job.getName());
	}
}
